package tbalert.springmvc;

import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.UrlPathHelper;

import tbalert.session.SessionProvider;
import tbalert.web.SysConstants;
import tbalert.web.entity.Dwdm;

public class TbalertContextInterceptor extends HandlerInterceptorAdapter {
	public static Pattern addBrxx = Pattern.compile("brxx.*add.do");
	public static Pattern editBrxx = Pattern.compile("brxx.*edit.do");
	public static Pattern delBrxx = Pattern.compile("brxx.*del.do");
	public static Pattern cancelBrxx = Pattern.compile("brxx.*cancel.do");

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
			Object handler) throws Exception {
		Dwdm bean = (Dwdm) session.getAttribute(request, SysConstants.DWDM_KEY);
		String uri = getURI(request);
		// 不在验证的范围内
		if (exclude(uri)) {
			return true;
		}
		// 用户为null或者被删除跳转到登陆页面
		if (bean == null || bean.getDisabled()) {
			session.logout(request, response);
			response.sendRedirect(getLoginUrl(request));
			return false;
		}
		// 权限控制
		if (addBrxx.matcher(uri).find() && !bean.getRole().getAddBrxx()) {
			request.setAttribute(SysConstants.MESSAGE, MessageResolver.getMessage(request,
					"auth.notAddBrxx"));
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return false;
		}
		if (delBrxx.matcher(uri).find() && !bean.getRole().getDelBrxx()) {
			request.setAttribute(SysConstants.MESSAGE, MessageResolver.getMessage(request,
					"auth.notDelBrxx"));
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return false;
		}
		if (editBrxx.matcher(uri).find() && !bean.getRole().getEditBrxx()) {
			request.setAttribute(SysConstants.MESSAGE, MessageResolver.getMessage(request,
					"auth.notEditBrxx"));
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return false;
		}
		if (uri.equals("/ymjg/add.do") && !bean.getRole().getAddYmjg()) {
			request.setAttribute(SysConstants.MESSAGE, MessageResolver.getMessage(request,
					"auth.notAddYmjg"));
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return false;
		}
		if (uri.equals("/ymjg/edit.do") && !bean.getRole().getEditYmjg()) {
			request.setAttribute(SysConstants.MESSAGE, MessageResolver.getMessage(request,
					"auth.notEditYmjg"));
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return false;
		}
		if (uri.startsWith("/admin/") && !bean.getRole().getAdmin()) {
			request.setAttribute(SysConstants.MESSAGE, MessageResolver.getMessage(request,
					"auth.notAdmin"));
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return false;
		}
		return true;
	}

	// 在检验路径之外
	private boolean exclude(String uri) {
		if (excludeUrls != null) {
			for (String exc : excludeUrls) {
				if (exc.equals(uri)) {
					return true;
				}
			}
		}
		return false;
	}

	private String getLoginUrl(HttpServletRequest request) {
		StringBuilder buff = new StringBuilder();
		if (loginUrl != null && loginUrl.startsWith("/")) {
			String ctx = request.getContextPath();
			if (!StringUtils.isBlank(ctx)) {
				buff.append(ctx);
			}
		}
		buff.append(loginUrl);
		return buff.toString();
	}

	/**
	 * 获得第三个路径分隔符的位置
	 * 
	 * @param request
	 * @throws IllegalStateException
	 *             访问路径错误，没有三(四)个'/'
	 */
	private static String getURI(HttpServletRequest request) throws IllegalStateException {
		UrlPathHelper helper = new UrlPathHelper();
		String uri = helper.getOriginatingRequestUri(request);
		String ctxPath = helper.getOriginatingContextPath(request);
		int start = 0, i = 0, count = 0;
		if (!StringUtils.isBlank(ctxPath)) {
			count++;
		}
		while (i < count && start != -1) {
			start = uri.indexOf('/', start + 1);
			i++;
		}
		if (start <= 0) {
			throw new IllegalStateException("access path not '/...' pattern: " + uri);
		}
		return uri.substring(start);
	}

	private String loginUrl;
	private String[] excludeUrls;

	@Autowired(required = true)
	private SessionProvider session;

	public void setLoginUrl(String loginUrl) {
		this.loginUrl = loginUrl;
	}

	public void setExcludeUrls(String[] excludeUrls) {
		this.excludeUrls = excludeUrls;
	}

}
